Le copy-on-write ou copie à l’écriture (souvent désigné par son sigle anglais COW) est une stratégie d'optimisation utilisée en programmation informatique. L'idée fondamentale : si de multiples appelants demandent des ressources initialement impossibles à distinguer, vous pouvez leur donner des pointeurs vers la même ressource. Cette fiction peut être maintenue jusqu'à ce qu'un appelant modifie sa « copie » de la ressource. À ce moment-là, une copie privée est créée. Cela évite que le changement soit visible ailleurs. Ceci se produit de manière transparente pour les appelants. L'avantage principal est que si un appelant ne fait jamais de modifications, la copie privée n'est jamais créée.
L'utilisation principale du Copy-on-write est la mémoire virtuelle de systèmes d'exploitation. Lorsqu'un processus crée une copie de lui-même, les pages de la mémoire qui doivent être modifiées soit par le processus soit par sa copie sont marquées copy-on-write. Lorsque le processus modifie une page mémoire, le noyau du système d'exploitation intercepte l'opération et copie la page mémoire pour que les changements de la mémoire d'un processus n'affectent pas celle d'un autre.
Une autre utilisation est la fonction calloc. Elle peut être implémentée en ayant une page de mémoire vive remplie par des zéros. Quand la mémoire est allouée, les pages retournées font toutes référence à la page de zéros et sont marquées copy-on-write. De cette façon, la quantité de mémoire vive allouée pour le processus n'augmente pas tant que les données ne sont pas écrites dans le tampon retourné par calloc. Typiquement, cela n'est fait que pour les allocations mémoire importantes.
Le Copy-on-write peut être implémenté en disant à la MMU que certaines pages dans l'espace d'adresses du processus sont en lecture seule. Quand des données sont écrites dans ces pages, la MMU lève une exception qui est gérée par le noyau. Celui-ci alloue de la mémoire vive et fait que la page écrite corresponde à ce nouvel endroit de la mémoire vive.
L'utilisation frugale de la mémoire est un avantage majeur du COW. Puisque l'utilisation de la mémoire vive ne s'accroît que quand des données sont stockées, des tables de hachage très efficaces peuvent être implémentées. Elles utilisent à peine plus de mémoire que les objets qu'elles contiennent. Néanmoins, de tels programmes risquent de tomber à court d'espace de mémoire virtuelle. Les pages virtuelles non utilisées par la table de hachage ne peuvent pas être utilisées par d'autres parties du programme. Le principal problème du COW au niveau du noyau est la complexité qu'il ajoute, mais les soucis sont similaires à ceux levés par des problématiques plus basiques de la mémoire virtuelle comme paginer vers le disque. Quand le noyau écrit ces pages, il doit les copier comme si elles étaient marquées copy-on-write.
Le COW peut être utilisé en dehors du noyau, dans des bibliothèques logicielles, du logiciel applicatif ou système. La classe string
fournie par la Standard Template Library de C++ a été conçue pour supporter des implémentations COW. Un des risques du COW dans ces contextes provient du code avec plusieurs processus légers où des verrous additionnels sont requis pour les objets dans différents processus légers pour qu'ils partagent la même représentation. La complexité d'implémentation induite peut annuler les bénéfices supposés de la technique COW.
Illustration de la technique de COW dans la STL C++
std::string x("Hello");
std::string y = x; // x et y utilisent le même tampon
y += ", World!"; // maintenant y utilise un tampon différent
// x continue à utiliser le même buffer
Les logiciels de virtualisation/émulation tels que Bochs, QEMU ou UML utilisent le COW pour le stockage virtuel sur disque. Cela permet une grande réduction de l'espace disque requis quand de multiples machines virtuelles sont fondées sur la même image disque. De plus les performances sont accrues car les lectures sur le disque peuvent être cachées en RAM et les lectures suivantes pour les autres machines virtuelles peuvent être servies à partir du cache.